package cn.com.zcode.exam.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import org.hibernate.Query;
import org.hibernate.Session;

import cn.com.zcode.core.dao.BaseHibernateDaoSupport;
import cn.com.zcode.exam.model.Answer;
import cn.com.zcode.exam.model.Examination;
import cn.com.zcode.exam.model.Option;
import cn.com.zcode.exam.model.Paper;
import cn.com.zcode.exam.model.Question;
import cn.com.zcode.exam.model.StaticInfo;
import cn.com.zcode.exam.model.Wrong;
import cn.com.zcode.user.model.User;

public class ExamDaoImpl extends BaseHibernateDaoSupport implements ExamDao {

	public synchronized Question addQuestion(Question question) {
		Paper paper = question.getPaper();
		if (question.getNo() == null) {
			Session session = this.getSession();
			Query query = session.getNamedQuery("getNo");
			query.setString("paperId", paper.getId());
			Integer maxid = (Integer) query.uniqueResult();
			question.setNo(maxid == null ? 1 : maxid);
		}
		String type = paper.getType();
		question.setPtype(type);
		List<Question> accessory = question.getAccessorys();
		if (accessory != null) {
			for (Question quest : accessory) {
				quest.setPtype(type);
				quest.setNo(question.getNo());
				quest.setChapter(question.getChapter());
				quest.setAnswer(question.getAnswer());
				quest.setPaper(paper);
			}
		}
		this.save(question);
		return question;
	}

	@Override
	public List<Question> listQuestions(String pmp) {
		return this.findByHQL("from Question ", Question.class);
	}

	@Override
	public Paper getPaperById(String pid) {
		return this.getByHQL("from Paper where id = ?", Paper.class, pid);
	}

	@Override
	public List<Paper> listPapersInfo(String key, String userid) {
		String hql = "from Paper where type = ? and (creater.id = ? or state= ?)";
		return this.findByHQL(hql, Paper.class, key, userid, Paper.STATE_PUBLIC);
	}

	@Override
	public Wrong getWrong(String userId, String questionId) {
		return this.getByHQL("from Wrong where questionId=? and userId=?", Wrong.class, questionId, userId);
	}

	@Override
	public List<Question> findMyWrongQuestionsByType(String type, String userId) {
		Session session = this.getSession();
		Query query = session.getNamedQuery("Examination.findMyWrongQuestionsByType");
		query.setString("type", type);
		query.setString("userId", userId);
		List<?> data = query.list();
		List<Question> list = null;
		if (data != null) {
			list = new ArrayList<Question>();
			for (Object obj : data) {
				Object[] arr = (Object[]) obj;
				Question question = (Question) arr[0];
				Wrong wrong = (Wrong) arr[1];
				question.setWrong(wrong);
				list.add(question);
			}
		}
		return list;
	}

	@Override
	public List<StaticInfo> listStaticInfoByType(String string) {
		String sql = "SELECT new cn.com.zcode.exam.model.StaticInfo(q.chapter, count(q.chapter)) FROM " + " Wrong e, Question q,Dictionary d where e.question.id = q.id and d.code = q.chapter GROUP BY q.chapter order by d.scort asc";
		Query query = this.getSession().createQuery(sql);
		@SuppressWarnings("unchecked")
		List<StaticInfo> result = query.list();
		return result;
	}

	@Override
	public Paper getPaper(String type, String title, int state, String userid) {
		if (state == 0) {
			return this.getByHQL("from Paper p where p.type = ? and p.title = ? and  p.state=0)", Paper.class, type, title);
		} else {
			return this.getByHQL("from Paper p where p.type = ? and p.title = ? and  p.state=? and p.creater.id = ?)", Paper.class, type, title, state, userid);
		}
	}

	@Override
	public List<StaticInfo> getPaperInfo(String type) {
		String hql = "SELECT new cn.com.zcode.exam.model.StaticInfo(d.title, count(q.chapter)) " + " FROM Question q,Dictionary d WHERE	q.ptype = ? and	d.code =q.chapter GROUP BY	q.chapter  ORDER BY	d.scort ASC";

		return this.findByHQL(hql, StaticInfo.class, type);
	}

	@Override
	public List<Question> searchQuestions(String keyword, String userId) {
		// String hql =
		// "from Question  where questionInfo.state!=? and (questionInfo.userId = ? or questionInfo.state=?) and ( summary like ? or no=?)";
		String hql = "from Question where  ( summary like ? or no=?) and primaryId is null";
		keyword = keyword.trim();
		String kparm = "%" + keyword + "%";
		int id = 0;
		if (Pattern.matches("^\\d+$", keyword)) {
			id = Integer.parseInt(keyword);
		}
		// return this.findByHQL(hql, Question.class, Paper.STATE_WRONG, userId,
		// Paper.STATE_PUBLIC, kparm, id);
		return this.findByHQL(hql, Question.class, kparm, id);
	}

	@Override
	public Question getQuestion(String id) {
		String hql = "from Question where id = ?";
		return this.getByHQL(hql, Question.class, id);
	}

	@Override
	public List<Examination> listExamination(String key, String userid) {

		String hql = "from Examination where paper.type = ? and user.id = ?";
		return this.findByHQL(hql, Examination.class, key, userid);

	}

	@Override
	public List<Question> listNewExamQuestions(String pid) {
		String hql = "select q from Question q  where questionInfo.id = ? ";
		return this.findByHQL(hql, Question.class, pid);
	}

	@Override
	public List<Question> listLastExamQuestions(String eid) {
		String hql = "select q from Question q, Examination e  where  e.id = ? and q.id not in (select a.questionId from Answer a where a.examId=? )";
		return this.findByHQL(hql, Question.class, eid, eid);
	}

	@Override
	public List<Paper> findPaperByUser(String type, User user) {
		Session session = this.getSession();
		Query query = session.getNamedQuery("findPaperByUser");
		query.setString("type", type);
		query.setString("userId", user.getId());
		List<Paper> list = query.list();
		return list;
	}

	@Override
	public Examination getLastExamination(String paperId, String userId) {
		String hql = "from Examination e where e.paper.id = ? and e.user.id = ? and e.state = ?";

		return this.getByHQL(hql, Examination.class, paperId, userId, Examination.ACTIVE);
	}

	@Override
	public List<Paper> findEditablePaper(String type, String id) {
		String hql = "from Paper where type = ? and (state = 0 or creater.id = ?)";
		return this.findByHQL(hql, Paper.class, type, id);
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Question> findRemainingQuestions(String eid, int length, String[] out) {
		Session session = this.getSession();
		Query query = session.getNamedQuery("Examination.findRemainingQuestions");
		query.setString("eid", eid);
		query.setParameterList("out", out);
		query.setMaxResults(length);
		List<Question> list = query.list();
		return list;
	}

	@Override
	public void savePaper(String id, Paper paper) {
		Session session = this.getSession();
		session.save(id, paper);

	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Question> findRemainingWrongQuestions(String eid, int length, String[] out) {
		Session session = this.getSession();
		Query query = session.getNamedQuery("Examination.findRemainingWrongQuestions");
		query.setString("eid", eid);
		query.setParameterList("out", out);
		query.setMaxResults(length);
		List<Question> list = query.list();
		return list;
	}

//	@Override
//	public void saveFinishExamination(exa) {
//		String hql = " Update Examination set endTime =:endTime ,state=:state,score =:score where id =:eid ";
//		Query query = this.getSession().createQuery(hql);
//		query.setParameter("endTime", new Date());
//		query.setParameter("eid", eid);
//		query.setInteger("state", state);
//		query.setDouble("score", score);
//		int a = query.executeUpdate();
//		System.out.println("===>:" + a);
//	}

	@Override
	public List<Answer> getAllAnswers(String eid) {
		String hql = "from Answer where examId = ?";
		return this.findByHQL(hql, Answer.class, eid);
	}

	@Override
	public int getWrongQuestionsCount(String eid) {
		Session session = this.getSession();
		Query query = session.getNamedQuery("Examination.getWrongQuestionsCount");
		query.setString("eid", eid);
		int num = (int) query.uniqueResult();
		return num;
	}

	@Override
	public int getQuestionsCount(String eid) {
		Session session = this.getSession();
		Query query = session.getNamedQuery("Examination.getQuestionsCount");
		query.setString("eid", eid);
		int num = (int) query.uniqueResult();
		return num;
	}

	@Override
	public List<Answer> findDoneAnswers(String eid) {
		String hql = "from Answer where examId = ? order by answerDate";
		return this.findByHQL(hql, Answer.class, eid);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Option> findOptionsByQids(Collection<String> qids) {
		String hql = "from Option where questionId in (:qids) order by questionId,no";
		Query query = getSession().createQuery(hql);
		query.setParameterList("qids", qids);
		return query.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Question> findAccessoriesByQids(Collection<String> qids) {
		Session session = this.getSession();
		Query query = session.getNamedQuery("Question.findAccessoriesByQids");
		query.setParameterList("qids", qids);
		List<Question> list = query.list();
		return list;
	}

	@Override
	public List<Question> getDoneInfo(String eid,boolean isForWrong) {
		Session session = this.getSession();
		Query query = session.getNamedQuery(isForWrong?"Examination.getDoneInfoForWrong":"Examination.getDoneInfoForNormal");
		query.setString("eid", eid);
		List<?> data = query.list();
		List<Question> list = null;
		if (data != null) {
			list = new ArrayList<Question>();
			for (Object obj : data) {
				Object[] arr = (Object[]) obj;
				Question question = (Question) arr[0];
				Answer answer = (Answer) arr[1];
				if(answer.getQuestionId()!=null){
					question.setAnswerInfo(answer);
				}
				System.out.println(answer);
				list.add(question);
			}
		}
	
		return list;
	}

	 
	
	
	
}
